package com.pdh.dao.imp;

import com.pdh.bean.Courier;
import com.pdh.dao.BaseCourierDao;
import com.pdh.exception.DuplicatePhoneException;
import com.pdh.exception.UnHandleException;
import com.pdh.util.DruidUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: 彭德华
 * @Date 2021-08-29 22:19
 */
public class CourierDaoMysql extends DruidUtil implements BaseCourierDao {
    //courier_count:总用户 day_reg_count:今日新增用户
    public static final String SQL_CONSOLE_COURIER = "SELECT COUNT(STATUS IN(0,1,2)) courier_count,COUNT(TO_DAYS(CREATE_TIME)=TO_DAYS(NOW()) OR NULL) day_reg_count FROM COURIER";
    //查找所有
    private static final String SQL_FIND_ALL = "ELECT *,INET6_NTOA(LOGIN_IP) IP FROM COURIER";
    //查找指定的起始索引 指定个数的数据
    private static final String SQL_FIND_LIMIT = "SELECT *,INET6_NTOA(LOGIN_IP) IP FROM COURIER LIMIT ?,?";
    //通过快递员手机号查找
    private static final String SQL_FIND_BY_COURIER_PHONE = "SELECT *,INET6_NTOA(LOGIN_IP) IP FROM COURIER WHERE COURIER_PHONE = ?";
    //插入数据(快递员名字,快递员电话,快递员身份证号码,秘密,注册时间)
    private static final String SQL_INSERT = "INSERT INTO COURIER(COURIER_NAME,COURIER_PHONE,PASSWORD,COURIER_ID_CARD_NO,CREATE_TIME) VALUES(?,?,?,?,NOW())";
    //更新指定id数据(快递员名字,快递员电话,快递员身份证号码,秘密)
    private static final String SQL_UPDATE = "UPDATE COURIER SET COURIER_NAME=?,COURIER_PHONE=?,PASSWORD=?,COURIER_ID_CARD_NO=?,STATUS=? WHERE ID=?";
    //删除指定id数据
    private static final String SQL_DELETE = "UPDATE COURIER SET STATUS=3 WHERE ID = ?";

    //更新数据库中存储的登陆时间 三个预编译参数
    private static final String SQL_LOGIN = "SELECT ID FROM COURIER WHERE COURIER_PHONE=?";
    private static final String SQL_UPDATE_LOGIN_INFO = "UPDATE COURIER SET STATUS=1,LOGIN_TIME=NOW(),LOGIN_IP=INET6_ATON(?) WHERE COURIER_PHONE=?";




    //把数据库连接、sql语句配置和查询的数据 实例化向上抽取，避免代码冗余
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;

    //封装一些简单的方法 获取一个新的express类 在此之前必须确定resultSet为非空！！
    private static final Courier getNewCourier(ResultSet resultSet) throws SQLException {
        int id = resultSet.getInt("id");
        String courierName = resultSet.getString("courier_name");
        String courierPhone = resultSet.getString("courier_phone");
        String password = resultSet.getString("password");
        String courierIdCardNo = resultSet.getString("courier_id_card_no");
        int status = resultSet.getInt("status");
        int deliveryCount = resultSet.getInt("delivery_count");
        Timestamp loginTime = resultSet.getTimestamp("login_time");
        String loginIp = resultSet.getString("ip");
        Timestamp createTime = resultSet.getTimestamp("create_time");
        Timestamp updateTime = resultSet.getTimestamp("update_time");
        return new Courier(id,courierName,courierPhone,password,courierIdCardNo,status,deliveryCount,loginTime,loginIp,createTime,updateTime);
    }

    /**
     * 于查询数据库中的快递员信息(快递员数量，日注册量)
     *
     * @return [{size:总数,day:新增}]
     */
    @Override
    public Map<String, Integer> consoleCourier() throws UnHandleException {
        Map<String,Integer> data = new HashMap<>();
        //1.获取数据库的连接
        connection = getConnection();
        //2.预编译sql语句
        try {
            statement = connection.prepareStatement(SQL_CONSOLE_COURIER);
            //3.填充参数(可选)
            //4.执行sql语句
            resultSet = statement.executeQuery();//执行查询语句
            //5.获取执行结果
            if(resultSet.next()){//首先明确得到的是些什么数据，而不是照着教程敲
                int courierCount = resultSet.getInt("courier_count");//
                int dayRegCount = resultSet.getInt("day_reg_count");
                data.put("courierCount",courierCount);
                data.put("dayRegCount",dayRegCount);
            }
        } catch (SQLException e) {
            UnHandleException unHandle = new UnHandleException(e.getMessage());
            throw unHandle;
        }finally {
            //6.资源释放
            close(connection,statement,resultSet);
        }
        return data;
    }

    /**
     * 用于查询所有的快递员
     *
     * @param paging      是否分页标记 true/false 分页/查询所有
     * @param offset     sql语句起始索引
     * @param limit 页查询的数量
     * @return 快递员的集合
     */
    @Override
    public List<Courier> findAll(boolean paging, int offset, int limit) throws UnHandleException {
        ArrayList<Courier> data = new ArrayList<>();
        //1.获取数据库连接
        connection = getConnection();
        try {
            //2.编译sql语句
            if(paging){
                statement = connection.prepareStatement(SQL_FIND_LIMIT);
                //3.填充参数
                statement.setInt(1,offset);
                statement.setInt(2,limit);
            }else {
                statement = connection.prepareStatement(SQL_FIND_ALL);
            }
            //4.执行sql语句
            resultSet = statement.executeQuery();
            //5.获取结果
            while (resultSet.next()){
                Courier courier = getNewCourier(resultSet);
                data.add(courier);
            }
        } catch (SQLException e) {
            UnHandleException unHandle = new UnHandleException(e.getMessage());
            throw unHandle;
        } finally {
            close(connection,statement,resultSet);
        }
        return data;
    }

    /**
     * 根据快递员手机号查询用户信息
     *
     * @param courierPhone 快递员手机号
     * @return 查询的快递员信息，手机号不存在时间放回null
     */
    @Override
    public Courier findByCourierPhone(String courierPhone) throws UnHandleException {
        //1.获取数据库连接
        connection = getConnection();
        try {
            //2，编译sql语句
            statement = connection.prepareStatement(SQL_FIND_BY_COURIER_PHONE);
            //3.填充参数
            statement.setString(1,courierPhone);
            //4.执行sql语句
            resultSet = statement.executeQuery();
            //5.把查询结果进行转换以便发送给前端
            if(resultSet.next()){
                Courier courier = getNewCourier(resultSet);
                return courier;
            }
        } catch (SQLException e) {
            UnHandleException unHandle = new UnHandleException(e.getMessage());
            throw unHandle;
        } finally {
            close(connection,statement,resultSet);
        }
        return null;
    }

    /**
     * 快递员的插入
     *
     * @param courier 录入的快递员对象
     * @return true/false
     */
    @Override
    public boolean insert(Courier courier) throws DuplicatePhoneException, UnHandleException {
        //1.获取数据库连接
        connection = getConnection();
        try {
            //2，编译sql语句
            statement = connection.prepareStatement(SQL_INSERT);
            //3.填充参数 COURIER_NAME,COURIER_PHONE,PASSWORD,COURIER_ID_CARD_NO
            statement.setString(1,courier.getCourierName());
            statement.setString(2,courier.getCourierPhone());
            statement.setString(3,courier.getPassword());
            statement.setString(4,courier.getCourierIdCardNo());
            //4.执行sql语句
            return statement.executeUpdate()>0?true:false;
        } catch (SQLException e) {
            if(e.getMessage().endsWith("for key 'uk_phone'")){
                //uk_phone重复出错
                DuplicatePhoneException phoneDuplicate = new DuplicatePhoneException(e.getMessage());
                throw phoneDuplicate;
            }else {
                //其他错误暂不处理
                UnHandleException unHandle = new UnHandleException(e.getMessage());
                throw unHandle;
            }
        } finally {
            close(connection,statement,null);
        }
    }

    /**
     * 更新快递员的信息
     *
     * @param id         待更新的快递员编号
     * @param newCourier 更新后的快递员对象
     * @return true/false
     */
    @Override
    public boolean update(int id, Courier newCourier) throws DuplicatePhoneException, UnHandleException {
        connection = getConnection();
        //2.编译sql语句
        try {
            statement = connection.prepareStatement(SQL_UPDATE);
            //3.填充参数
            //COURIER_NAME=?,COURIER_PHONE=?,PASSWORD=?,COURIER_ID_CARD_NO=?,STATUS=? WHERE ID=?
            statement.setString(1,newCourier.getCourierName());
            statement.setString(2,newCourier.getCourierPhone());
            statement.setString(3,newCourier.getPassword());
            statement.setString(4,newCourier.getCourierIdCardNo());
            statement.setInt(5,newCourier.getStatus());
            statement.setInt(6,id);
            //4.执行sql
            return statement.executeUpdate()>0?true:false;
        } catch (SQLException e) {
            if(e.getMessage().endsWith("for key 'uk_phone'")){
                //uk_phone重复出错
                DuplicatePhoneException phoneDuplicate = new DuplicatePhoneException(e.getMessage());
                throw phoneDuplicate;
            }else {
                //其他错误暂不处理
                UnHandleException unHandle = new UnHandleException(e.getMessage());
                throw unHandle;
            }
        } finally {
            //6.释放资源
            close(connection,statement,null);
        }
    }

    /**
     * 根据快递员id删除快递员信息
     * 为什么不用userPhone进行删除，因为可能一个号码对应多个用户，就删除了多个用户
     *
     * @param id 待删除快递员id
     * @return true/false
     */
    @Override
    public boolean delete(int id) throws UnHandleException {
        //1.获取数据库的连接
        connection = getConnection();
        //2.预编译sql语句
        try {
            statement = connection.prepareStatement(SQL_DELETE);
            //3.填充参数(可选)
            statement.setInt(1,id);
            //4.执行sql语句
            return statement.executeUpdate()>0?true:false;
        } catch (SQLException e) {
            //其他错误暂不处理
            UnHandleException unHandle = new UnHandleException(e.getMessage());
            throw unHandle;
        }finally {
            //6.资源释放
            close(connection,statement,null);
        }
    }

    /**
     * 用户登陆语句
     *
     * @param courierPhone
     * @return
     */
    @Override
    public boolean login(String courierPhone) throws UnHandleException {
        //1.获取数据库的连接
        connection = getConnection();
        //2.预编译sql语句
        try {
            statement = connection.prepareStatement(SQL_LOGIN);
            //3.填充参数(可选)
            statement.setString(1, courierPhone);
            //4.执行sql语句
            resultSet = statement.executeQuery();
            return resultSet.next();
        } catch (SQLException e) {
            //抛出未收录的异常，之后还可以编写异常处理
            throw new UnHandleException(e.getMessage());
        }  finally {
            //6.资源释放
            close(connection, statement, null);
        }
    }

    /**
     * 更新用户登陆信息
     *
     * @param courierPhone
     * @param ip
     * @return
     */
    @Override
    public boolean updateLoginInformation(String courierPhone, String ip) throws UnHandleException {
        //1.获取连接
        connection = getConnection();
        //2.预编译sql语句
        try {//try/catch更有利于释放资源
            statement = connection.prepareStatement(SQL_UPDATE_LOGIN_INFO);//体验命名规范
            //3.填充参数
            statement.setString(1,ip);
            statement.setString(2,courierPhone);
            //4.执行
            int row = statement.executeUpdate();//不需要获取结果 学框架以后可以更多的去关注这些东西使得项目数据更加稳健
            return row>0?true:false;
        } catch (SQLException e) {
            //抛出未收录的异常，之后还可以编写异常处理
            throw new UnHandleException(e.getMessage());
        }finally {
            //5.释放资源
            close(connection,statement,null);
        }
    }
}
